package x.ovo.wechat.bot.plugin;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.cache.CacheUtil;
import org.dromara.hutool.core.cache.impl.TimedCache;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.text.StrUtil;
import x.ovo.wechat.bot.core.Constant;
import x.ovo.wechat.bot.core.event.EventListener;
import x.ovo.wechat.bot.core.event.MessageEvent;
import x.ovo.wechat.bot.core.message.TextMessage;
import x.ovo.wechat.bot.core.plugin.Plugin;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "AiListener")
public class AiListener extends EventListener<MessageEvent<TextMessage>, TextMessage> {

    private static final Map<String, String> FREE_TALK = new HashMap<>(16);
    private static final TimedCache<String, String> CACHE = CacheUtil.newTimedCache(TimeUnit.MINUTES.toMicros(15), TimeUnit.MINUTES.toMillis(5));

    public AiListener(Plugin plugin) {
        super(plugin);
    }

    @Override
    public boolean support(@NonNull MessageEvent<TextMessage> event, TextMessage message) {
        // 开启自由对话的用户或者消息正文包含关键词
        return FREE_TALK.containsKey(message.isGroup() ? message.getMember().getUserName() : message.getFrom().getUserName()) ||
                this.plugin.<List<String>>getConfig().getOrDefault("keywords", List.of()).stream()
                        .anyMatch(keyword -> message.getContent().startsWith(keyword));
    }

    @Override
    public boolean onEvent(@NonNull MessageEvent<TextMessage> event, TextMessage message) {
        String username = message.isGroup() ? message.getMember().getUserName() : message.getFrom().getUserName();
        if (this.setting(message, username)) {
            return true;
        }

        // 绘图
        if (message.getContent().startsWith("draw ")) {
            File file = null;
            try {
                file = DrawService.draw(this.plugin.getDataDir(), message.getContent().substring(5));
                message.getFrom().sendImage(file);
            } catch (Exception e) {
                log.error("绘图失败");
                message.getFrom().sendMessage("绘图失败");
            } finally {
                if (Objects.nonNull(file) && file.exists())
                    FileUtil.del(file);
            }
            return true;
        }

        // 如果用户已经开启自由对话，在消息正文前加上对应的模型
        if (FREE_TALK.containsKey(username)) message.setContent(FREE_TALK.get(username) + " " + message.getContent());
        this.handleTalk(message);
        return true;
    }

    private boolean setting(TextMessage message, String username) {
        if (!message.getContent().startsWith("ai ")) return false;
        String[] split = message.getContent().split(" ");
        if (split.length < 2) throw new RuntimeException("参数错误");
        // 获取帮助信息
        if (("help".equals(split[1]) || "帮助".equals(split[1]))) {
            message.getFrom().sendMessage(this.plugin.<String>getConfig().get("help"));
            return true;
        }

        String groupHead = message.isGroup() ? StrUtil.format("@{} {}{}", message.getMember().getNickName(), message.getContent(), Constant.delimiter) : "";
        // 开启自由对话
        if ("start".equals(split[1])) {
            if (FREE_TALK.containsKey(username)) {
                message.getFrom().sendMessage(groupHead + "你已经开启过自由对话了，当前对话模型为[" + FREE_TALK.get(username) + "]，如果需要关闭，请发送 ai stop");
                return true;
            }
            String model = split.length > 2 ? split[2] : "qwen";
            FREE_TALK.put(username, model);
            message.getFrom().sendMessage(groupHead + "开启自由对话成功，当前对话模型为[" + model + "]，如果需要关闭，请发送 ai stop");
            return true;
        }

        // 关闭自由对话
        if ("stop".equals(split[1])) {
            if (FREE_TALK.containsKey(username)) {
                FREE_TALK.remove(username);
                message.getFrom().sendMessage(groupHead + "关闭自由对话成功");
                return true;
            }
        }
        return false;
    }

    private void handleTalk(TextMessage message) {
        Prompt prompt = Prompt.NULL;
        String[] split = message.getContent().split(" ", 2);
        String model = split[0];
        message.setContent(split[1]);
        if (split[0].contains("-")) {
            model = split[0].split("-")[0];
            prompt = Prompt.get(split[0].split("-")[1]);
        }
        String cacheKey = model + "::" + message.getFrom().getUserName() + (message.isGroup() ? message.getMember().getUserName() : "");
        if ("clear".equals(split[1]) || "清除".equals(split[1]) || "清除会话".equals(split[1])) {
            CACHE.remove(cacheKey);
            message.getFrom().sendMessage("会话清除成功");
            return;
        }

        Map<String, Object> config = this.plugin.<Map<String, Object>>getConfig().get(model);
        String id = StrUtil.defaultIfBlank(CACHE.get(cacheKey, true), "");
        Talker.Param param = Talker.Param.builder().id(id).host((String) config.get("host")).prompt(prompt).message(message).tokens((List<String>) config.get("token")).build();
        id = message.isGroup() ? Talker.talk(param) : Talker.talkStream(param);
        if (!CACHE.containsKey(cacheKey) && StrUtil.isNotBlank(id)) CACHE.put(cacheKey, id);
    }


    @Override
    public boolean executeNext() {
        return false;
    }
}
